﻿using System;
using System.Threading.Tasks;
using System.Windows.Input;

namespace HYGE.AsyncCommand
{
    /// <summary>
    /// IAsyncCommand実装用の基底抽象クラス。
    /// </summary>
    public abstract class AsyncCommandBase : IAsyncCommand
    {
        #region ICommandMembers

        #region Events

        #region CanExecuteChanged
        /// <summary>
        /// ICommand.CanExecuteChanged。
        /// </summary>
        public event EventHandler CanExecuteChanged = null;

        /// <summary>
        /// コマンドが実行可能かどうかが変化した際に実行される。
        /// </summary>
        protected virtual void OnCanExecuteChanged()
        {
            EventHandler handler = null;
            handler = this.CanExecuteChanged;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }
        #endregion

        #endregion

        #region Methods

        #region CanExecute
        /// <summary>
        /// ICommand.CanExecute(object)の明示的実装。
        /// CanExecute(object)に処理移譲。
        /// 継承クラスでCanExecute(object)のシグネチャを隠したいため定義。
        /// </summary>
        /// <param elementName="parameter"></param>
        /// <returns></returns>
        bool ICommand.CanExecute(object parameter)
        {
            return (this.CanExecute(parameter));
        }

        /// <summary>
        /// CanExecute実装用の抽象メソッド。
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        protected abstract bool CanExecute(object parameter);
        #endregion

        #region Execute
        /// <summary>
        /// ICommand.Execute(object)の明示的実装。
        /// Execute(object)に処理移譲。
        /// 継承クラスでExecute(object)のシグネチャを隠したいため定義。
        /// </summary>
        /// <param name="parameter"></param>
        void ICommand.Execute(object parameter)
        {
            this.Execute(parameter);
        }

        /// <summary>
        /// Execute実装用の抽象メソッド。
        /// </summary>
        /// <param name="parameter"></param>
        protected abstract void Execute(object parameter);
        #endregion

        #endregion

        #endregion

        #region IAsyncCommandMembers

        #region Events

        #region JobCreated
        /// <summary>
        /// IAsyncCommand.JobCreated。
        /// </summary>
        public event EventHandler<JobCreatedEventArgs> JobCreated = null;

        /// <summary>
        /// ジョブが作成された際に実行される。
        /// </summary>
        /// <param name="job"></param>
        protected virtual void OnJobCreated(IAsyncJob job)
        {
            EventHandler<JobCreatedEventArgs> handler = null;
            handler = this.JobCreated;
            if (handler != null)
                handler(this, new JobCreatedEventArgs(job));
        }
        #endregion

        #endregion

        #region Properties

        #region Scheduler
        /// <summary>
        /// IAsyncCommand.Schedulerの実装。
        /// </summary>
        public TaskScheduler Scheduler
        {
            get;
            set;
        }
        #endregion

        #endregion

        #region Methods

        #region RaiseCanExecuteChanged
        /// <summary>
        /// コマンドが実行可能かどうかが変化したことを通知する。
        /// </summary>
        public void RaiseCanExecuteChanged()
        {
            this.OnCanExecuteChanged();
        }
        #endregion

        #endregion

        #endregion
    }
}
